有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java ClientServersocket只能发送1个文件

我正在做一个示例客户机-服务器socket项目,其中服务器向客户机发送一个文件,客户机将其保存在目标文件夹中。它运行良好,但只运行一次。我必须重新启动服务器并重新连接客户端才能发送另一个文件

我做错了什么

服务器:

public void doConnect() {
        try {
            InetAddress addr = InetAddress.getByName(currentIPaddress);
            serverSocket = new ServerSocket(4445, 50, addr);

            isServerStarted = true;

            socket = serverSocket.accept();

            inputStream = new ObjectInputStream(socket.getInputStream());
            outputStream = new ObjectOutputStream(socket.getOutputStream());
            String command = inputStream.readUTF();
            this.statusBox.setText("Received message from Client: " + command);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

用于从服务器发送文件的方法

public void sendFile() {
        fileEvent = new FileEvent();
        String fileName = sourceFilePath.substring(sourceFilePath.lastIndexOf("/") + 1, sourceFilePath.length());
        String path = sourceFilePath.substring(0, sourceFilePath.lastIndexOf("/") + 1);
        fileEvent.setDestinationDirectory(destinationPath);
        fileEvent.setFilename(fileName);
        fileEvent.setSourceDirectory(sourceFilePath);
        File file = new File(sourceFilePath);
        if (file.isFile()) {
            try {
                DataInputStream diStream = new DataInputStream(new FileInputStream(file));
                long len = (int) file.length();
                byte[] fileBytes = new byte[(int) len];
                int read = 0;
                int numRead = 0;
                while (read < fileBytes.length && (numRead = diStream.read(fileBytes, read, fileBytes.length - read)) >= 0) {
                    read = read + numRead;
                }
                fileEvent.setFileSize(len);
                fileEvent.setFileData(fileBytes);
                fileEvent.setStatus("Success");
            } catch (Exception e) {
                e.printStackTrace();
                fileEvent.setStatus("Error");
            }
        } else {
            System.out.println("path specified is not pointing to a file");
            fileEvent.setStatus("Error");
        }
        //Now writing the FileEvent object to socket
        try {
            outputStream.writeUTF("newfile");
            outputStream.flush();

            outputStream.writeObject(fileEvent);

            String result = inputStream.readUTF();
            System.out.println("client says: " + result);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

客户

public void connect() {
        int retryCount = 0;

        while (!isConnected) {
            if (retryCount < 5) {
                try {
                    socket = new Socket(currentIPAddress, currentPort);

                    outputStream = new ObjectOutputStream(socket.getOutputStream());
                    inputStream = new ObjectInputStream(socket.getInputStream());
                    isConnected = true;

                    //connection success
                    String command = inputStream.readUTF();

                    if (command.equals("newfile")) {
                        this.clientCmdStatus.setText("Received a file from Server");
                        outputStream.writeUTF("Thanks Server! Client Received the file");
                        outputStream.flush();
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        }
                        new Thread(new DownloadingThread()).start();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    retryCount++;
                }
            } else {
                //Timed out. Make sure Server is running & Retry
                retryCount = 0;
                break;
            }
        }
    }

用于在客户端下载文件的代码

public void downloadFile() {
        try {
            fileEvent = (FileEvent) inputStream.readObject();
            if (fileEvent.getStatus().equalsIgnoreCase("Error")) {
                System.out.println("Error occurred ..So exiting");
                System.exit(0);
            }

            String outputFile = destinationPath + fileEvent.getFilename();

            if (!new File(destinationPath).exists()) {
                new File(destinationPath).mkdirs();
            }

            dstFile = new File(outputFile);
            fileOutputStream = new FileOutputStream(dstFile);
            fileOutputStream.write(fileEvent.getFileData());
            fileOutputStream.flush();
            fileOutputStream.close();
            System.out.println("Output file : " + outputFile + " is successfully saved ");
            serverResponsesBox.setText("File received from server: " + fileEvent.getFilename());

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

共 (1) 个答案

  1. # 1 楼答案

    为了让服务器接受另一个(或更多)连接,必须将其放入循环中

    while(someConditionIndicatingYourServerShouldRun) {
       Socker socket = serverSocket.accept();
       //respond to the client
    
    }
    

    我建议使用线程池并将处理提交到线程池,即使用ExecutorService。此外,您应该在完成后关闭资源,例如stream,“try with Resources”结构可以帮助您完成这一任务。所以你的代码可能是这样的

    ServerSocket serverSocket =  ...;
    ExecutorService threadPool = Executors.newFixedThreadPool(10);
    AtomicBoolean running = new AtomicBoolean(true);
    while(running.get()) {
      Socket socket = serverSocket.accept();
      threadPool.submit(() -> {
        try(ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
            OutputStream os = new ObjectOutputStream(socket.getOutputStream())) {
            String command = is.readUTF();
            if("shutdown".equals(command)) {
              running.set(false);
            } else {
              this.statusBox.setText("Received message from Client: " + command);    
            }   
        } catch (IOException e) {
          e.printStackTrace();
        }
      });
    }